/*
 * Copyright 2023, Haiku, Inc.
 * Distributed under the terms of the MIT License.
 */
#ifndef CPU_STATE_LOONGARCH64_H
#define CPU_STATE_LOONGARCH64_H

#include <bitset>

#include <debugger.h>

#include "CpuState.h"


enum {
	// 通用寄存器
	LOONGARCH64_REGISTER_R0 = 0,  // 零寄存器
	LOONGARCH64_REGISTER_RA,      // 返回地址寄存器
	LOONGARCH64_REGISTER_TP,      // 线程指针寄存器
	LOONGARCH64_REGISTER_SP,      // 栈指针寄存器
	LOONGARCH64_REGISTER_A0,      // 函数参数/返回值寄存器
	LOONGARCH64_REGISTER_A1,      // 函数参数/返回值寄存器
	LOONGARCH64_REGISTER_A2,      // 函数参数寄存器
	LOONGARCH64_REGISTER_A3,      // 函数参数寄存器
	LOONGARCH64_REGISTER_A4,      // 函数参数寄存器
	LOONGARCH64_REGISTER_A5,      // 函数参数寄存器
	LOONGARCH64_REGISTER_A6,      // 函数参数寄存器
	LOONGARCH64_REGISTER_A7,      // 函数参数寄存器
	LOONGARCH64_REGISTER_T0,      // 临时寄存器
	LOONGARCH64_REGISTER_T1,      // 临时寄存器
	LOONGARCH64_REGISTER_T2,      // 临时寄存器
	LOONGARCH64_REGISTER_T3,      // 临时寄存器
	LOONGARCH64_REGISTER_T4,      // 临时寄存器
	LOONGARCH64_REGISTER_T5,      // 临时寄存器
	LOONGARCH64_REGISTER_T6,      // 临时寄存器
	LOONGARCH64_REGISTER_T7,      // 临时寄存器
	LOONGARCH64_REGISTER_T8,      // 临时寄存器
	LOONGARCH64_REGISTER_S0,      // 保存寄存器
	LOONGARCH64_REGISTER_S1,      // 保存寄存器
	LOONGARCH64_REGISTER_S2,      // 保存寄存器
	LOONGARCH64_REGISTER_S3,      // 保存寄存器
	LOONGARCH64_REGISTER_S4,      // 保存寄存器
	LOONGARCH64_REGISTER_S5,      // 保存寄存器
	LOONGARCH64_REGISTER_S6,      // 保存寄存器
	LOONGARCH64_REGISTER_S7,      // 保存寄存器
	LOONGARCH64_REGISTER_S8,      // 保存寄存器
	LOONGARCH64_REGISTER_PC,      // 程序计数器

	LOONGARCH64_INT_REGISTER_END,

	// 浮点寄存器
	LOONGARCH64_REGISTER_F0,
	LOONGARCH64_REGISTER_F1,
	LOONGARCH64_REGISTER_F2,
	LOONGARCH64_REGISTER_F3,
	LOONGARCH64_REGISTER_F4,
	LOONGARCH64_REGISTER_F5,
	LOONGARCH64_REGISTER_F6,
	LOONGARCH64_REGISTER_F7,
	LOONGARCH64_REGISTER_F8,
	LOONGARCH64_REGISTER_F9,
	LOONGARCH64_REGISTER_F10,
	LOONGARCH64_REGISTER_F11,
	LOONGARCH64_REGISTER_F12,
	LOONGARCH64_REGISTER_F13,
	LOONGARCH64_REGISTER_F14,
	LOONGARCH64_REGISTER_F15,
	LOONGARCH64_REGISTER_F16,
	LOONGARCH64_REGISTER_F17,
	LOONGARCH64_REGISTER_F18,
	LOONGARCH64_REGISTER_F19,
	LOONGARCH64_REGISTER_F20,
	LOONGARCH64_REGISTER_F21,
	LOONGARCH64_REGISTER_F22,
	LOONGARCH64_REGISTER_F23,
	LOONGARCH64_REGISTER_F24,
	LOONGARCH64_REGISTER_F25,
	LOONGARCH64_REGISTER_F26,
	LOONGARCH64_REGISTER_F27,
	LOONGARCH64_REGISTER_F28,
	LOONGARCH64_REGISTER_F29,
	LOONGARCH64_REGISTER_F30,
	LOONGARCH64_REGISTER_F31,

	LOONGARCH64_FP_REGISTER_END,

	LOONGARCH64_REGISTER_COUNT
};


#define LOONGARCH64_INT_REGISTER_COUNT LOONGARCH64_INT_REGISTER_END
#define LOONGARCH64_FP_REGISTER_COUNT (LOONGARCH64_FP_REGISTER_END \
	- LOONGARCH64_INT_REGISTER_END)


class CpuStateLoongArch64 : public CpuState {
public:
								CpuStateLoongArch64();
								CpuStateLoongArch64(const loongarch64_debug_cpu_state& state);

	virtual					~CpuStateLoongArch64();

	virtual	status_t		Clone(CpuState*& _clone) const;

	virtual	status_t		UpdateDebugState(void* state, size_t size) const;

	virtual	target_addr_t	InstructionPointer() const;
	virtual	void				SetInstructionPointer(target_addr_t address);

	virtual	target_addr_t	StackFramePointer() const;
	virtual	target_addr_t	StackPointer() const;

	virtual	bool				GetRegisterValue(const Register* reg,
									BVariant& _value) const;
	virtual	bool				SetRegisterValue(const Register* reg,
									const BVariant& value);

				target_addr_t	IntRegisterValue(int32 index) const;
				void				SetIntRegister(int32 index, target_addr_t value);

				double				FpRegisterValue(int32 index) const;
				void				SetFpRegister(int32 index, double value);

				bool				IsRegisterSet(int32 index) const;


private:
			target_addr_t			fIntRegisters[LOONGARCH64_INT_REGISTER_COUNT];
			double					fFpRegisters[LOONGARCH64_FP_REGISTER_COUNT];
			std::bitset<LOONGARCH64_REGISTER_COUNT> fSetRegisters;
};


#endif	// CPU_STATE_LOONGARCH64_H